home *** CD-ROM | disk | FTP | other *** search
Wrap
Glydo.PrioritizedImageLoader = Prototype.Class.create(Glydo.EventSource,{ initialize: function($super,sources_to_try,prefetch,options) { $super(); this.options = options || {}; this.sources = sources_to_try; this.fetch = prefetch; this.waiting = false; this.startPrefetch(); }, startPrefetch: function() { this.cancelled = false; this.next = 0; this.succeeded = false; this.failed = false; this.tryNextImage(); }, completeFetch: function() { this.fetch = null; if (!this.done) { this.tryNextImage(); } }, get done() { return this.succeeded || this.failed; }, cancel: function() { this.cancelled = true; if (this.loader) { this.loader.src = null; delete this.loader; } this.next = 0; }, tryNextImage: function() { if (this.cancelled) { return; } if (this.waiting) { return; } if (this.next >= this.sources.length) { this.failed = true; this.fire('onImageLoadingFailure',this); return; } if ((this.fetch !== null) && this.next >= this.fetch) { return; } var loader = new Image(); var me = this; loader.onload = Prototype.F.bind(this.onLoadSuccess,this); loader.onerror = Prototype.F.bind(this.onLoadError,this); loader.onabort = Prototype.F.bind(this.onLoadError,this); this.loader = loader; this.cur = this.sources[this.next++]; if (typeof(this.cur) == "string") { loader.src = this.cur; } else { loader.src = this.cur.url; } this.waiting = true; }, onLoadError: function() { delete this.loader; this.waiting = false; this.tryNextImage(); }, onLoadSuccess: function() { this.waiting = false; if (this.cancelled) { return; } if (this.cur.validation && Prototype.O.isFunction(this.cur.validation)) { if (!this.cur.validation.call(this.cur,this.loader)) { this.onLoadError(); return; } } if (this.options.validation && Prototype.O.isFunction(this.options.validation)) { if (!this.options.validation.call(this.cur,this.loader)) { this.onLoadError(); return; } } this.image = this.loader; this.succeeded = true; this.fire('onImageLoadingSuccess',this); }, }); Glydo.BestThumbnailLoader = Prototype.Class.create(Glydo.PrioritizedImageLoader,{ initialize: function($super,targetWidth, targetHeight,thumbnailGroups,options) { this.targetWidth = targetWidth; this.targetHeight = targetHeight; this.thumbnailGroups = thumbnailGroups; var thumbnails_to_try = this.thumbnailGroups.map(this.prioritizeThumbnails,this).reduce( function (a,b) { return a.concat(b); },[]); var prefetch = null; for (var i = 0; i < thumbnails_to_try.length; ++i) { if (thumbnails_to_try[i].lazy) { prefetch = i; } } thumbnails_to_try = Prototype.A.pluck(thumbnails_to_try,"thumbnail"); $super(thumbnails_to_try,prefetch,options); }, prioritizeThumbnails: function(thumbnails) { var thumbnailsWithPenalties = thumbnails.map( function (thumbnail) { var xFactor = this.targetWidth / thumbnail.width; var yFactor = this.targetHeight / thumbnail.height; var factor = Math.max(Math.min(xFactor,yFactor,Glydo.BestThumbnailLoader.Consts.MAX_THUMBNAIL_SCALING_FACTOR),Glydo.BestThumbnailLoader.Consts.MIN_THUMBNAIL_SCALING_FACTOR); var resultWidth = factor * thumbnail.width; var resultHeight = factor * thumbnail.height; var overflowArea = 0; var underfillArea = 0; if (resultWidth > this.targetWidth) { overflowArea += (resultWidth - this.targetWidth) * resultHeight; } else { underfillArea += (this.targetWidth - resultWidth) * this.targetHeight; } if (resultHeight > this.targetHeight) { overflowArea += (resultHeight - this.targetHeight) * Math.min(resultWidth,this.targetWidth); } else { underfillArea += (this.targetHeight - resultHeight) * Math.min(resultWidth,this.targetWidth); } var areaPenalty = ( Glydo.BestThumbnailLoader.Consts.THUMBNAIL_UNDERFILL_PENALTY*underfillArea + Glydo.BestThumbnailLoader.Consts.THUMBNAIL_OVERFLOW_PENALTY*overflowArea) / (this.targetWidth * this.targetHeight); var factorPenalty = (factor > 1 ? Math.log(factor) / Math.log(Glydo.BestThumbnailLoader.Consts.MAX_THUMBNAIL_SCALING_FACTOR) : Math.log(factor) / Math.log(Glydo.BestThumbnailLoader.Consts.MIN_THUMBNAIL_SCALING_FACTOR)); var penalty = areaPenalty + factorPenalty; return ({ penalty: penalty, thumbnail: thumbnail, lazy: !!thumbnail.lazy}); },this); return thumbnailsWithPenalties.sort(function(a,b) { return a.penalty - b.penalty; }); }, }); Glydo.BestThumbnailLoader.Consts = { MAX_THUMBNAIL_SCALING_FACTOR: 1.1, MIN_THUMBNAIL_SCALING_FACTOR: 0.1, THUMBNAIL_UNDERFILL_PENALTY: 3.0, THUMBNAIL_OVERFLOW_PENALTY: 1.0, };